package com.jd.jr.pay.demo.util;

import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class SignUtil {
	private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SignUtil.class);

	private static List<String> unSignKeyList = java.util.Arrays
			.asList(new String[] { "merchantSign", "token", "version" });

	public static String sign4SelectedKeys(Object object, String rsaPriKey, List<String> signKeyList) {
		String result = "";
		try {
			String sourceSignString = signString4SelectedKeys(object, signKeyList);
			logger.info("sourceSignString:" + sourceSignString);

			String sha256SourceSignString = SHAUtil.Encrypt(sourceSignString, null);

			byte[] newsks = RSACoder.encryptByPrivateKey(sha256SourceSignString.getBytes("UTF-8"), rsaPriKey);
			result = RSACoder.encryptBASE64(newsks);
		} catch (Exception e) {
			logger.error("sign4SelectedKeys>error", e);
		}
		return result;
	}

	public static String signRemoveSelectedKeys(Object object, String rsaPriKey, List<String> signKeyList) {
		String result = "";
		try {
			String sourceSignString = signString(object, signKeyList);
			logger.info("sourceSignString:" + sourceSignString);

			String sha256SourceSignString = SHAUtil.Encrypt(sourceSignString, null);

			byte[] newsks = RSACoder.encryptByPrivateKey(sha256SourceSignString.getBytes("UTF-8"), rsaPriKey);
			result = RSACoder.encryptBASE64(newsks);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * @param object
	 * @param unSignKeyList
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * 把参数实体类转成待sign的字符串xx=xx&xx=xx
	 */
	public static String signString(Object object, List<String> unSignKeyList)
			throws IllegalArgumentException, IllegalAccessException {
		TreeMap<String, Object> map = objectToMap(object);

		StringBuilder sb = new StringBuilder();

		for (String str : unSignKeyList) {
			map.remove(str);
		}

		Iterator iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {
			Object entry = (Map.Entry) iterator.next();
			if ((((Map.Entry) entry).getValue() != null)
					&& (((String) ((Map.Entry) entry).getValue()).trim().length() > 0)) {
				sb.append((String) ((Map.Entry) entry).getKey() + "=" + (String) ((Map.Entry) entry).getValue() + "&");
			}
		}

		String result = sb.toString();
		if (result.endsWith("&")) {
			result = result.substring(0, result.length() - 1);
		}

		return result;
	}
	/**
	 * @param object
	 * @param unSignKeyList
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * 把参数实体类中的值转成待sign的字符串xxxx
	 */
	public static String signStringOnlyValue(Object object, List<String> unSignKeyList)
			throws IllegalArgumentException, IllegalAccessException {
		TreeMap<String, Object> map = objectToMap(object);
		
		StringBuilder sb = new StringBuilder();
		
		for (String str : unSignKeyList) {
			map.remove(str);
		}
		
		Iterator iterator = map.entrySet().iterator();
		while (iterator.hasNext()) {
			Object entry = (Map.Entry) iterator.next();
			if ((((Map.Entry) entry).getValue() != null)
					&& (((String) ((Map.Entry) entry).getValue()).trim().length() > 0)) {
				sb.append((String) ((Map.Entry) entry).getKey() + "=" + (String) ((Map.Entry) entry).getValue() + "&");
			}
		}
		
		String result = sb.toString();
		if (result.endsWith("&")) {
			result = result.substring(0, result.length() - 1);
		}
		
		return result;
	}

	private static String signString4SelectedKeys(Object object, List<String> signedKeyList)
			throws IllegalArgumentException, IllegalAccessException {
		TreeMap<String, Object> map = objectToMap(object);
		if ((map == null) || (map.isEmpty()) || (signedKeyList == null) || (signedKeyList.isEmpty())) {
			return null;
		}

		TreeMap<String, Object> signMap = new TreeMap();

		StringBuilder sb = new StringBuilder();

		for (String str : signedKeyList) {
			Object o = map.get(str);
			if (o != null) {
				signMap.put(str, o);
			} else {
				signMap.put(str, "");
			}
		}

		Iterator iterator = signMap.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry entry = (Map.Entry) iterator.next();
			sb.append(entry.getKey() + "=" + (entry.getValue() == null ? "" : entry.getValue()) + "&");
		}

		String result = sb.toString();
		if (result.endsWith("&")) {
			result = result.substring(0, result.length() - 1);
		}
		return result;
	}

	/**
	 * @param object
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * 把实体类转成
	 */
	public static TreeMap<String, Object> objectToMap(Object object)
			throws IllegalArgumentException, IllegalAccessException {
		TreeMap<String, Object> map = new TreeMap();

		for (Class<?> cls = object.getClass(); cls != Object.class; cls = cls.getSuperclass()) {
			Field[] fields = cls.getDeclaredFields();
			Field[] arrayOfField1;
			int j = (arrayOfField1 = fields).length;
			for (int i = 0; i < j; i++) {
				Field f = arrayOfField1[i];
				f.setAccessible(true);
				map.put(f.getName(), f.get(object));
			}
		}
		return map;
	}
}
